home *** CD-ROM | disk | FTP | other *** search
/ Cracking 2 / Cracking II..iso / Texty / crackme / tc_id13.txt < prev    next >
Encoding:
Text File  |  1999-05-29  |  8.0 KB  |  209 lines

  1. Target: CrackMe [id:13]
  2. Author: tC...
  3. Cracker: The AntiXryst [CrossOver]
  4. Rating: Easy. I know tC... having written worse things.
  5. Used tools: WDASM 8.93, Hex Workshop
  6. Greetings to: Me, myself and I and everybody else I injured during my
  7.           sadomasochistic games ;-)
  8.  
  9.  
  10. Hi there!
  11.  
  12. You have probably read my tutorial on getting past tC's CrackMe id:12.
  13. If you did not and now do not know how to find relevant procedures of
  14. Delphi-written programs, read it NOW!
  15.  
  16. As you may already have experienced, I will NOT explain every single
  17. detail, I'll just show you what part of code does what in a syntactical
  18. mix of Pascal and ASM register calling...
  19. If you browse through the disassembly and get closer to its sense,
  20. you'll soon recognise that the Delphi compiler is VERY stupid and
  21. produces completely inefficient, sometimes even idiotic code.
  22.  
  23. And now launch WDASM, disassemble the crackme and set a breakpoint to
  24. $00441908, what is actually "our" routine. Feel free either just to
  25. read my text or to follow my steps with the debugger...
  26.  
  27.  
  28. Code snippet $00441924-$004419B0:
  29. ---------------------------------
  30. String data from the input boxes is read through the Delphi VCL and
  31. stored in pre-defined memory offsets. You'll find a string reference to
  32. "Yeah, You did it!" followed by a call - do not worry, this is just a
  33. hoax, because the called routine $00403850 has no relevance for the
  34. generation of serial numbers/key values due to its position in the VCL
  35. fully linked to the executable and because the value returned by this
  36. function in EAX is ignored by XOR EAX,EAX ($00441931).
  37.  
  38.  
  39.  
  40. Code snippet $004419B5-$004419C8:
  41. ---------------------------------
  42. A relevant function is called - $004418D0. It seems to test something.
  43. This routine stores its result in [$00443838]. If this result is 2, the
  44. program continues. Elseway it calls a "clean-up" routine at $004417E4
  45. which deletes some calculated values and memory-stored string data from
  46. the input boxes, after the call returns, the jump to $00441AF5 is
  47. performed thus "our" relevant routine is terminated.
  48.  
  49.  
  50.  
  51. Subroutines $004418D0 and $004418AC:
  52. ------------------------------------
  53. The routine $004418D0 does perform a check whether memory-stored string
  54. values from the upper 2 input boxes are longer than 0. You could also
  55. say that this function checks whether the values have been entered at
  56. all. If both values are present, routine $004418AC is called.
  57. The routine $004418AC performs via subtraction a compare of string
  58. lengths. If they are same, $00443838 becomes 2.
  59.  
  60.  
  61.  
  62. Code snippet $004419DC-$00441A17:
  63. ---------------------------------
  64. In this code snippet the entered serial number is validated without a
  65. correct serial number is being generated.
  66.  
  67. :004419DC lea edx, dword ptr [ebp-08]      <---- getting User entry
  68. :004419DF mov eax, dword ptr [esi+000002C4]      from input box
  69. :004419E5 call 004231A4                 via VCL call
  70.  
  71. :004419EA mov eax, dword ptr [ebp-08]      <---- offset of User
  72. :004419ED movzx eax, byte ptr [eax+ebx-01] <---- ASCII value is loaded,
  73. :004419F2 add eax, 00000003                      increased by 3
  74. :004419F5 push eax               <---- and stored
  75.  
  76. :004419F6 lea edx, dword ptr [ebp-0C]      <---- getting Serial entry
  77. :004419F9 mov eax, dword ptr [esi+000002C8]      from input box
  78. :004419FF call 004231A4                 via VCL call
  79.  
  80. :00441A04 mov eax, dword ptr [ebp-0C]      <---- offset of Serial
  81. :00441A07 movzx eax, byte ptr [eax+ebx-01] <---- getting ASCII value
  82. :00441A0C pop edx               <---- loading User char+3
  83. :00441A0D sub edx, eax
  84. :00441A0F add dword ptr [00443840], edx    <---- difference between
  85.                          User char+3 and Serial
  86.                          char
  87.  
  88. :00441A15 inc ebx               <---- EBX is index counter
  89. :00441A16 dec edi               <---- EDI is loop counter
  90. :00441A17 jne 004419DC
  91.  
  92. You can sum up this in a sort of Pascal syntax:
  93.        var index:Cardinal;
  94.        for index:=1 to Length(User) do
  95.     [00443840]:=[00443840]+(Ord(Name[index])+3-Ord(Serial[index]));
  96.  
  97.  
  98.  
  99. Code snippet $00441A19-$00441A25:
  100. ---------------------------------
  101. A call to the routine $0044182C is performed. This routine is a hoax,
  102. intended to confuse the cracker. Why? Surely it does some string mani-
  103. pulation with XOR, addition and subtraction. But it does not store any
  104. calculated values ;-) After the call, offset $00443840 is checked
  105. whether it's 0. If not, the routine terminates. Do you see that the
  106. manipulated string and the serial must match? So here's the algorithm:
  107.        var index:Cardinal;
  108.        Serial:='';
  109.        for index:=1 to Length(User) do
  110.         Serial:=Serial+Chr(Ord(User[index])+3);
  111.  
  112.  
  113.  
  114. Code snippet $00441A31-$00441A3D:
  115. ---------------------------------
  116. The string value for RegCode is obtained through the VCL and checked,
  117. whether it has been entered (length > 0). If the string is not present,
  118. the routine terminates.
  119.  
  120.  
  121.  
  122. Code snippet $00441A49-$00441A7D:
  123. ---------------------------------
  124. A call to the hoax routine $004418AC is performed. The length of Serial
  125. and RegCode are checked, they must be the same, elseway the routine
  126. terminates.
  127.  
  128. :00441A5E mov eax, dword ptr [00443848]    <---- offset of RegCode
  129. :00441A63 call 00403A34            <---- call to Length()
  130. :00441A68 mov ebx, eax            <---- result stored
  131. :00441A6A mov eax, dword ptr [0044384C] <---- offset to Serial
  132. :00441A6F call 00403A34            <---- call to Length()
  133. :00441A74 cmp ebx, eax            <---- compare the lengths
  134. :00441A76 je 00441A7F            <---- if OK, then continue
  135.  
  136.  
  137.  
  138. Code snippet $00441A89-$00441A:
  139. ---------------------------------
  140. In this code snippet the entered RegCode is validated without a valid
  141. RegCode is being generated. This is the same as the validation of the
  142. Serial string, there's just one difference - instead of increasing by 3
  143. the chars of the user name are decreased by 3.
  144.  
  145. :00441A8E lea edx, dword ptr [ebp-08]        <---- getting User entry
  146. :00441A91 mov eax, dword ptr [esi+000002C4]
  147. :00441A97 call 004231A4
  148.  
  149. :00441A9C mov eax, dword ptr [ebp-08]        <---- now decreasing its
  150. :00441A9F movzx eax, byte ptr [eax+ebx-01]      chars by 3
  151. :00441AA4 sub eax, 00000003
  152. :00441AA7 push eax                <---- storing
  153.  
  154. :00441AA8 lea edx, dword ptr [ebp-0C]       <---- getting RegCode entry
  155. :00441AAB mov eax, dword ptr [esi+000002D0]
  156. :00441AB1 call 004231A4
  157.  
  158. :00441AB6 mov eax, dword ptr [ebp-0C]       <---- again getting 1 char
  159. :00441AB9 movzx eax, byte ptr [eax+ebx-01]
  160. :00441ABE pop edx                           <---- "remembering" and
  161. :00441ABF sub edx, eax                            subtraction
  162. :00441AC1 add dword ptr [00443844], edx     <---- storing
  163.  
  164. :00441AC7 inc ebx
  165. :00441AC8 dec edi
  166. :00441AC9 jne 00441A8E
  167.  
  168. As you see, nearly the same as the Serial validation. The correct
  169. algorithm for creation of the RegCode:
  170.        var index:Cardinal;
  171.        RegCode:='';
  172.        for index:=1 to Length(User) do
  173.         RegCode:=RegCode+Chr(Ord(User[index])-3);
  174.  
  175.  
  176.  
  177. Code snippet $00441ACB-$00441AEB:
  178. ---------------------------------
  179. Here, 2 calls to another hoax routines are done. The difference of
  180. chars of RegCode and manipulated user name is checked, if not equal 0,
  181. the routine terminates.
  182.  
  183. :00441ACB call 00441870            <---- hoax routine
  184. :00441AD0 call 0044175C            <---- another hoax
  185. :00441AD5 mov eax, dword ptr [00443844] <---- getting the difference
  186.                           computed above
  187. :00441ADA add eax, 00027009        <---- just to confuse newbies
  188. :00441ADF cmp eax, 00027009             <---- if EAX was 0, now EAX
  189.                           must be $27009, thus the
  190.                           RegCode is recognized as
  191.                           valid.
  192. :00441AE4 je 00441AED            <---- if OK, then proceed
  193. :00441AE6 call 004417E4            <---- elseway terminate
  194. :00441AEB jmp 00441AF5
  195.  
  196.  
  197.  
  198. That's all, folks! Now it's up to you to write a working keygen. Or if
  199. you are as lazy as me, myself and I, you may play with my keygen.
  200. -----------------------------------------------------------------------
  201.  
  202. I hope you have learned a little bit from this. Look out for my cracks:
  203. tutorials or source codes are included in most cases!
  204.  
  205. Sincerely yours,
  206.   The AntiXryst [CrossOver]
  207.  
  208. Visit the newcoming cracking group I am the CoLeader of:
  209. http://crossover.tsx.org